﻿#include "ScriptThread.h"
#include <QFile>
#include <QTextStream>
#include <QDebug>

#include "PythonAgent.h"
#include "BaseModule/GlobalEnums.h"
#include "BaseModule/IBaseSignal.h"
#include "BaseModule/GlobalHelper.h"

namespace ScriptManager
{

    ScriptThread::ScriptThread(PythonAgent* agent, QStringList listPYCode, bool isGui)
    {
        m_isPYCode = true;
        m_listPYCode = listPYCode;
        m_agent = agent;
        m_isGui = isGui;
    }

    ScriptThread::ScriptThread(PythonAgent* agent, QString filePath, bool isGui)
    {
        m_isPYCode = false;
        m_filePath = filePath;
        m_agent = agent;
        m_isGui = isGui;
        m_filePathList.append(filePath);
    }

    ScriptThread::~ScriptThread()
    {
    }

    void ScriptThread::run()
    {
        //读取文件中的python代码
        if (!m_isPYCode)
        {
            QFile _file(m_filePath);
            if (!_file.open(QIODevice::Text | QIODevice::ReadOnly))
            {
                emit IBaseSignalInstance->signal_showMessageToConsole(BaseModule::EMessageConsole::Error, tr("Script open failed"));
                return;
            }

            QTextStream _stream(&_file);
            _stream.setCodec("UTF-8");
            while (!_stream.atEnd())
            {
                QString line = _stream.readLine().simplified();
                if (!line.contains('#'))
                {
                    m_listPYCode.append(line);
                }
            }

            _file.close();
        }

        if (!(m_listPYCode.size()))
        {
            emit IBaseSignalInstance->signal_showMessageToConsole(BaseModule::EMessageConsole::Error, tr("Script code list is empty"));
            return;
        }
        GlobalHelperInstance->setIsPythonRunning(true);
        //执行python配置代码
        m_agent->submitFromScriptThread(m_listPara, true);

        //执行python代码集合
        for (int _index = 0; _index < m_listPYCode.size();)
        {
            if (m_lockCount > 0) continue;
            //当m_lockCount为0时表示上一条命令已经执行完成，这时可以执行下一条命令
            auto _code = m_listPYCode.at(_index);
            ++_index;
            m_commandIndex = _index;
            if (_code.isEmpty()) continue;

            recordLock();
            m_agent->submitFromScriptThread(_code, false);

            //是python对象，并且函数名字中不包含thread字符串
            if (isPythonObj(_code) && !_code.toLower().contains("run_thread"))
            {
                releaseLock();
            }
        }
        
        //注意:此段循环代码在release模式下可能会有问题
        while (m_lockCount > 0)
        {
            msleep(10);
        }

        if (m_isStop)
        {
            if (m_isPYCode)
            {
                emit IBaseSignalInstance->signal_showMessageToConsole(BaseModule::EMessageConsole::Warning, tr("Script executed failed!"));
            }
            else
            {
                emit IBaseSignalInstance->signal_showMessageToConsole(BaseModule::EMessageConsole::Warning, tr("Script stop execution : %1").arg(m_filePath));
            }
            ////提示导入案例失败
            //if (m_isImportExample)
            //{
            //    if (!m_isNoGui)
            //    {
            //        BaseModule::MessageBoxButton result;
            //        emit IBaseSignalInstance->signal_showMessageDialog(tr("Import Example"), tr("Failed import of example!"), BaseModule::MessageBoxType::Warning, result);
            //    }
            //    emit IBaseSignalInstance->signal_showMessageToConsole(BaseModule::EMessageConsole::Warning, tr("Failed import of example!"));
            //}
        }
        else
        {
            if (m_isPYCode)
            {
                emit IBaseSignalInstance->signal_showMessageToConsole(BaseModule::EMessageConsole::Normal, tr("Script executed complete!"));
            }
            else
            {
                emit IBaseSignalInstance->signal_showMessageToConsole(BaseModule::EMessageConsole::Normal, tr("Script executed %1 complete.").arg(m_filePath));
            }
            ////提示导入案例成功
            //if (m_isImportExample)
            //{
            //    if (!m_isNoGui)
            //    {
            //        BaseModule::MessageBoxButton result;
            //        emit IBaseSignalInstance->signal_showMessageDialog(tr("Import Example"), tr("Successful import of example!"), BaseModule::MessageBoxType::Normal, result);
            //    }
            //    emit IBaseSignalInstance->signal_showMessageToConsole(BaseModule::EMessageConsole::Normal, tr("Successful import of example!"));
            //}
        }

        if (!m_isGui)
        {
            emit IBaseSignalInstance->signal_closeApp();
        }
        else
        {
            //emit IBaseSignalInstance->signal_reRender();
        }
        GlobalHelperInstance->setIsPythonRunning(false);
    }

    void ScriptThread::recordLock()
    {
        m_lockCount++;
        qDebug() << "lock";
    }
    void ScriptThread::releaseLock()
    {
        m_lockCount--;
        if (m_lockCount < 0)
        {
            m_lockCount = 0;
        }
        qDebug() << "unlock";
    }

    void ScriptThread::stop()
    {
        m_listPYCode.clear();
        m_isStop = true;
        m_lockCount = 0;

        //提示导入案例失败
        //if (m_isImportExample)
        //{
        //    if (!m_isNoGui)
        //    {
        //        BaseModule::MessageBoxButton result;
        //        emit IBaseSignalInstance->signal_showMessageDialog(tr("Import Example"), tr("Failed import of example!"), BaseModule::MessageBoxType::Warning, result);
        //    }
        //    emit IBaseSignalInstance->signal_showMessageToConsole(BaseModule::EMessageConsole::Warning, tr("Failed import of example!"));
        //}

        //if (!m_isPYCode)
        //{
        //    emit m_agent->signal_showMessageToConsole(BaseModule::EMessageConsole::Warning, tr("Script executed %1 stops!").arg(m_filePath));
        //    emit IBaseSignalInstance->signal_updateProjectTree();
        //}
        //if (m_isNoGui)
        //{
        //    emit m_agent->signal_closeMainWindow();
        //}
    }

    bool ScriptThread::getIsRun()
    {
        return !m_isStop;
    }

    void ScriptThread::setPara(QStringList listPara)
    {
        m_listPara = listPara;
    }

    bool ScriptThread::isPythonObj(QString code)
    {
        //如果当前行包含=，则表示是在创建对象
        if (code.contains("="))
        {
            return true;
        }

        //如果当前行包含.，则表示是对象在调用函数
        QStringList cs = code.split(".");
        if (cs.at(0).toLower() == cs.at(0))
        {
            return true;
        }

        return false;
    }

    bool ScriptThread::appendCommand(QString filePath, QStringList command)
    {
        if (filePath.isEmpty() == false)
        {
            if (m_filePathList.contains(filePath))
            {
                stop();
                IBaseSignalInstance->signal_sendErrorMessageToUI(QStringLiteral("不允许重复执行相同的脚本文件，已停止后续脚本执行！"));
                return false;
            }
            else
            {
                m_filePathList.append(filePath);
            }
        }
        for (int i = 0; i < command.count(); ++i)
        {
            m_listPYCode.insert(m_commandIndex+i, command[i]);
        }
        return true;
    }

    void ScriptThread::setIsImportExample()
    {
        m_isImportExample = true;
    }

}
